﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QSettings>
#include <qDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

initialiseSingleton(MainWindow);

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow),
      m_currentWebSocketClient(NULL),
      m_currentclient(NULL)
{
    ui->setupUi(this);

    m_ScriptEditDialog = new ScriptEditDialog(this);
    m_ShowLogDialog = new ShowLogDialog(this);
    m_AddClientDialog = new AddClientDialog(this);
    m_AboutDialog = new AboutDialog(this);

    connect(m_ScriptEditDialog, SIGNAL(scriptfileitemDoubleClicked(QString)), this, SLOT(onprocessscriptfileitemDoubleClicked(QString)));
    connect(m_ScriptEditDialog, SIGNAL(scriptfileupdate(QString,QString)), this, SLOT(onprocessscriptfileupdate(QString,QString)));

    //connect(ui->listWidget, SIGNAL(customContextMenuRequested(QPoint)),this, SLOT(on_listWidget_customContextMenuRequested(QPoint)));
    ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);

    ui->tabWidget->clear();
    ui->tabWidget->addTab(m_ShowLogDialog,QString::fromLocal8Bit("系统日志"));
    ui->tabWidget->addTab(m_ScriptEditDialog,QString::fromLocal8Bit("脚本编辑"));

    LoadClients();

    this->showMaximized();
}

MainWindow::~MainWindow()
{
    m_CWebSocketClientManager.clearAllClients();

    delete ui;

    delete m_ScriptEditDialog;
    delete m_ShowLogDialog;
    delete m_AddClientDialog;
    delete m_AboutDialog;
}

QString MainWindow::JsonToString(const QJsonObject& json)
{
    return QString(QJsonDocument(json).toJson(QJsonDocument::Compact));
}

QJsonObject MainWindow::StringToJson(const QString& str)
{
    QJsonObject l_ret;

    QJsonParseError l_err;
    QJsonDocument l_doc = QJsonDocument::fromJson(str.toUtf8(), &l_err);
    if (l_err.error == QJsonParseError::NoError)
    {
        if (l_doc.isObject())
        {
            l_ret = l_doc.object();
        }
    }
    return l_ret;
}

void MainWindow::on_action_triggered()
{
    int state = m_AddClientDialog->exec();

    if(state == 1)
    {
        if(isExistClient(m_AddClientDialog->getInputIp(),
                         m_AddClientDialog->getInputPort().toInt(),
                         m_AddClientDialog->getInputDebugPort().toInt()) == NULL)
        {
            tagClients ptagClients;
            ptagClients.ip = m_AddClientDialog->getInputIp();
            ptagClients.port = m_AddClientDialog->getInputPort().toInt();
            ptagClients.debugport = m_AddClientDialog->getInputDebugPort().toInt();

            m_Clients.push_back(ptagClients);

            ui->listWidget->addItem(ptagClients.ip+
                                    "_"+
                                    QString::asprintf("%d",ptagClients.port)+
                                    "_"+
                                    QString::asprintf("%d",ptagClients.debugport));

            QSettings settings("YunDa","clients");

            settings.setValue("clientcount",m_Clients.size());

            for(int i=0;i<m_Clients.size();i++)
            {
                settings.setValue("ip",m_Clients[i].ip);
                settings.setValue("port",m_Clients[i].port);
                settings.setValue("debugport",m_Clients[i].debugport);
            }
        }
    }
}

tagClients* MainWindow::isExistClient(QString ip,int port,int debugport)
{
    for(int i=0;i<m_Clients.size();i++)
    {
        if(m_Clients[i].ip == ip &&
                m_Clients[i].port == port &&
                m_Clients[i].debugport == debugport)
            return &m_Clients[i];
    }

    return NULL;
}

tagClients* MainWindow::getClientByName(QString clientname)
{
    if(clientname.isEmpty())
        return NULL;

    QStringList stringlist = clientname.split("_");
    if(stringlist.size() != 3)
        return NULL;

    return isExistClient(stringlist[0],stringlist[1].toInt(),stringlist[2].toInt());
}

void MainWindow::LoadClients(void)
{
    QSettings settings("YunDa","clients");

    int pclientcount = settings.value("clientcount").toInt();

    for(int i=0;i<pclientcount;i++)
    {
        tagClients ptagClients;
        ptagClients.ip = settings.value("ip").toString();
        ptagClients.port = settings.value("port").toInt();
        ptagClients.debugport = settings.value("debugport").toInt();

        m_Clients.push_back(ptagClients);

        ui->listWidget->addItem(ptagClients.ip+
                                "_"+
                                QString::asprintf("%d",ptagClients.port)+
                                "_"+
                                QString::asprintf("%d",ptagClients.debugport));
    }
}

void MainWindow::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{
    m_currentclient = MainWindow::getClientByName(item->text());
    if(m_currentclient == NULL)
        return;

    CWebSocketClient *pWebSocketClient = m_CWebSocketClientManager.getClient(item->text());

    if(pWebSocketClient != NULL && m_currentWebSocketClient == pWebSocketClient)
        return;

    if(pWebSocketClient != NULL)
    {
        disconnect(pWebSocketClient, SIGNAL(socketmessage(QWebSocket*,QString)), this, SLOT(onprocesssocketmessage(QWebSocket*,QString)));
        disconnect(pWebSocketClient, SIGNAL(socketconnected(QWebSocket*)), this, SLOT(onprocesssocketconnected(QWebSocket*)));
        disconnect(pWebSocketClient, SIGNAL(socketdisconnected(QWebSocket*)), this, SLOT(onprocesssocketdisconnected(QWebSocket*)));

        m_CWebSocketClientManager.deleteClient(item->text());
    }

    pWebSocketClient = new CWebSocketClient(this);
    pWebSocketClient->Open("ws://"+m_currentclient->ip+":"+QString::asprintf("%d",m_currentclient->port));

    m_CWebSocketClientManager.addClient(item->text(),pWebSocketClient);

    connect(pWebSocketClient, SIGNAL(socketmessage(CWebSocketClient*,QString)), this, SLOT(onprocesssocketmessage(CWebSocketClient*,QString)));
    connect(pWebSocketClient, SIGNAL(socketconnected(CWebSocketClient*)), this, SLOT(onprocesssocketconnected(CWebSocketClient*)));
    connect(pWebSocketClient, SIGNAL(socketdisconnected(CWebSocketClient*)), this, SLOT(onprocesssocketdisconnected(CWebSocketClient*)));

    m_currentWebSocketClient = pWebSocketClient;
}

void MainWindow::onprocesssocketmessage(CWebSocketClient *pwebsocket,QString message)
{
    if(message.isEmpty())
        return;

    QJsonObject reciverJson = StringToJson(message);

    switch(reciverJson["MsgId"].toInt())
    {
    case IDD_MESSAGE_LOG:
    {
        QString type = reciverJson["type"].toString();
        QString content = reciverJson["content"].toString();

        if(type == "waring")
            content = "<font color=green>" + content + "</font>";
        else if(type == "info")
            content = "<font color=white>" + content + "</font>";
        else if(type == "error")
            content = "<font color=red>" + content + "</font>";
        else
            content = "<font color=blue>" + content + "</font>";

        m_ScriptEditDialog->addLog(type,content);
        m_ShowLogDialog->addLog(content);
    }
        break;
    case IDD_MESSAGE_GETSCRIPT_FILES:
    {
        QJsonArray dataarray = reciverJson["data"].toArray();

        m_ScriptEditDialog->clearScriptFile();

        for(int i=0;i<dataarray.size();i++)
        {
            QJsonObject filedata = dataarray.at(i).toObject();

            m_ScriptEditDialog->addScriptFile(filedata["file"].toString());
        }
    }
        break;
    case IDD_MESSAGE_GETSCRIPT_CONTENT:
    {
        QString content = reciverJson["content"].toString();

        m_ScriptEditDialog->addScriptcontent(QByteArray::fromBase64(content.toLocal8Bit()));
    }
        break;
    case IDD_MESSAGE_UPDATESCRIPT:
    {
        QString filename = reciverJson["file"].toString();
        bool issuccesed = reciverJson["state"].toBool();

        if(issuccesed)
            ui->statusbar->showMessage(filename + QString::fromLocal8Bit(" 更新成功."));
        else
            ui->statusbar->showMessage(filename + QString::fromLocal8Bit(" 更新失败."));
    }
        break;
    default:
    {
        m_ShowLogDialog->addLog(message);
    }
        break;
    }
}

void MainWindow::onprocesssocketconnected(CWebSocketClient *pwebsocket)
{
    if(pwebsocket == NULL) return;

    QString message = pwebsocket->getUrl().host() + QString::fromLocal8Bit(" 连接成功!");
    ui->statusbar->showMessage(message);

    QString content = "<font color=white>" + message + "</font>";
    m_ShowLogDialog->addLog(content);
}

void MainWindow::onprocesssocketdisconnected(CWebSocketClient *pwebsocket)
{
    if(pwebsocket == NULL) return;

    QString message = pwebsocket->getUrl().host() + QString::fromLocal8Bit(" 断开连接!");
    ui->statusbar->showMessage(message);

    QString content = "<font color=white>" + message + "</font>";
    m_ShowLogDialog->addLog(content);
}

void MainWindow::on_tabWidget_currentChanged(int index)
{
    if(index == 1)
    {
        QJsonObject jsonobj;
        jsonobj["MsgId"] = IDD_MESSAGE_GETSCRIPT_FILES;

        if(m_currentWebSocketClient) m_currentWebSocketClient->Send(JsonToString(jsonobj));
    }
}

void MainWindow::onprocessscriptfileupdate(QString filepath,QString content)
{
    if(filepath.isEmpty() || content.isEmpty())
        return;

    QJsonObject jsonobj;
    jsonobj["MsgId"] = IDD_MESSAGE_UPDATESCRIPT;
    jsonobj["file"] = filepath;
    jsonobj["content"] = QString(content.toUtf8().toBase64());

    if(m_currentWebSocketClient) m_currentWebSocketClient->Send(JsonToString(jsonobj));
}

void MainWindow::onprocessscriptfileitemDoubleClicked(QString filepath)
{
    if(filepath.isEmpty())
        return;

    QJsonObject jsonobj;
    jsonobj["MsgId"] = IDD_MESSAGE_GETSCRIPT_CONTENT;
    jsonobj["file"] = filepath;

    if(m_currentWebSocketClient) m_currentWebSocketClient->Send(JsonToString(jsonobj));
}

void MainWindow::on_action_2_triggered()
{
    m_AboutDialog->exec();
}

void MainWindow::on_listWidget_customContextMenuRequested(const QPoint &pos)
{
    QListWidgetItem* curItem = ui->listWidget->itemAt( pos );
    if( curItem == NULL )
        return;

    QMenu *popMenu = new QMenu( this );
    QAction *deleteSeed = new QAction(QString::fromLocal8Bit("删除设备"), this);
    popMenu->addAction( deleteSeed );
    connect( deleteSeed, SIGNAL(triggered() ), this, SLOT( deleteSeedSlot()) );
    popMenu->exec( QCursor::pos() );
    delete popMenu;
    delete deleteSeed;
}

void MainWindow::deleteSeedSlot()
{
    QListWidgetItem * item = ui->listWidget->currentItem();
    if( item == NULL )
        return;

    m_currentclient = MainWindow::getClientByName(item->text());
    if(m_currentclient == NULL)
        return;

    QVector<tagClients>::iterator iter = m_Clients.begin();
    for(;iter != m_Clients.end();++iter)
    {
        if(iter->debugport == m_currentclient->debugport &&
              iter->ip == m_currentclient->ip &&
                iter->port == m_currentclient->port)
        {
            m_Clients.erase(iter);
            break;
        }
    }

    ui->listWidget->removeItemWidget(item);
    delete item;

    m_currentclient=NULL;
    m_currentWebSocketClient=NULL;

    QSettings settings("YunDa","clients");

    settings.setValue("clientcount",m_Clients.size());

    for(int i=0;i<m_Clients.size();i++)
    {
        settings.setValue("ip",m_Clients[i].ip);
        settings.setValue("port",m_Clients[i].port);
        settings.setValue("debugport",m_Clients[i].debugport);
    }
}
